package nl.hanze.shoestring.ui;

import java.awt.*;
import java.awt.event.*;
import java.util.Collections;
import java.util.List;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;
import nl.hanze.shoestring.domain.Deelnemer;
import nl.hanze.shoestring.domain.Klant;
import nl.hanze.shoestring.domain.Reservering;
import nl.hanze.shoestring.logic.Logic;
import nl.hanze.shoestring.logic.Rules;
import nl.hanze.shoestring.logic.Utils;

/**
 * DeelnemerPanel 
 * DeelnemerPanel is de GUI waarin de Deelnemers kunnen
 * worden opgevraagd en bewerkt.
 *
 * @author henk
 */
public class DeelnemerPanel extends JPanel {

    private static final long serialVersionUID = 1L;
    Logic logic;
    JPanel pQueryInput, pRecord, pNavigation, pDbGrid, cardReservering;
    JLabel lblZoekSleutel, lblId, lblKlant_id, lblReservering_id, lblBedrag, lblDieet, lblVerlenging;
    JTextField txtZoekSleutel, txtId, txtBedrag;
    JButton butZoeken, butSave, butDelete, butEmpty, butReservering;
    JCheckBox chkDieet;
    JCheckBox chkVerlenging;
    JComboBox cmbKlant_id;
    JComboBox cmbReservering_id;
    JTable table;
    JScrollPane scrollPaneRes;
    DefaultTableModel model;
    int heightField = 25;
    int numberOfRows = 13;
    
    List<Deelnemer> deelnemerList;
    List<Klant> klantList;
    ReserveringPanel reserveringPanel;
    Reservering selectedReservering = null;
    Deelnemer selectedDeelnemer = null;
    Deelnemer deelnemerObj = null;
    Klant klantObj = null;

    public DeelnemerPanel(Logic logic, final JPanel cardReservering) {
        this.logic = logic;
        this.cardReservering = cardReservering;

        table = new JTable();
        setLayout(new BorderLayout(20, 20));

        // GUI
        // input velden north sectie
        pQueryInput = new JPanel();
        pQueryInput.setLayout(null);
        pQueryInput.setPreferredSize(new Dimension(400, 110));

        lblZoekSleutel = UIHelper.createLabel(lblZoekSleutel = new JLabel(), "Zoeksleutel", 10, 10, 150, heightField, pQueryInput);
        txtZoekSleutel = UIHelper.createTextField(txtZoekSleutel = new JTextField(), "", 170, 10, 250, heightField, pQueryInput);

        txtZoekSleutel.addKeyListener(new KeyAdapter() {

            @Override
            public void keyReleased(KeyEvent e) {
                searchKlant();
            }
        
        });

        butZoeken = UIHelper.createButton(butZoeken = new JButton(), "Zoeken", 430, 10, 100, heightField, pQueryInput);
        butZoeken.addActionListener(
                new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        searchDeelnemer();
                    }
                });

        // Center sectie, database record
        pRecord = new JPanel();
        pRecord.setLayout(null);
        pRecord.setPreferredSize(new Dimension(400, 500));
        Border blueline = BorderFactory.createLineBorder(Color.blue);
        pRecord.setBorder(BorderFactory.createTitledBorder(blueline,"Deelnemer toevoegen",TitledBorder.CENTER,TitledBorder.ABOVE_TOP));

        lblId = UIHelper.createLabel(lblId = new JLabel(), "Nummer", 20, 20, 150, heightField, pRecord);
        txtId = UIHelper.createTextField(txtId = new JTextField(), "", 170, 20, 100, heightField, pRecord);

        lblReservering_id = UIHelper.createLabel(lblReservering_id = new JLabel(), "Reservering", 20, 50, 150, heightField, pRecord);
        cmbReservering_id = UIHelper.createCombo(cmbReservering_id = new JComboBox(), 170, 50, 300, heightField, pRecord);
        fillReserveringComboFields();        

        lblKlant_id = UIHelper.createLabel(lblKlant_id = new JLabel(), "Deelnemer", 20, 80, 150, heightField, pRecord);
        cmbKlant_id = UIHelper.createCombo(cmbKlant_id = new JComboBox(), 170, 80, 300, heightField, pRecord);
        fillKlantComboFields();        

        lblBedrag = UIHelper.createLabel(lblBedrag = new JLabel(), "Bedrag", 20, 110, 150, heightField, pRecord);
        txtBedrag = UIHelper.createTextField(txtBedrag = new JTextField(), "", 170, 110, 150, heightField, pRecord);

        lblDieet = UIHelper.createLabel(lblDieet = new JLabel(), "Dieet", 20, 140, 150, heightField, pRecord);
        chkDieet = UIHelper.createCheckBox(chkDieet = new JCheckBox(), "", 170, 140, 150, heightField, pRecord);

        lblVerlenging = UIHelper.createLabel(lblVerlenging = new JLabel(), "Verlenging", 20, 170, 150, heightField, pRecord);
        chkVerlenging = UIHelper.createCheckBox(chkVerlenging = new JCheckBox(), "", 170, 170, 150, heightField, pRecord);
        
        
                // buttons
                butSave = UIHelper.createButton(butSave = new JButton(), "Opslaan", 170, 210, 120, heightField, pRecord);
                butSave.addActionListener(
                        new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                if(isInputOk()) {
                                    if(deelnemerObj!=null) {
                                        updateRecord(deelnemerObj);
                                    } else {
                                        addRecord();
                                    }
                                }
                            }
                        });

                butDelete = UIHelper.createButton(butDelete = new JButton(), "Verwijderen", 350, 210, 120, heightField, pRecord);
                butDelete.addActionListener(
                        new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                System.out.println("delete");
                                if(deelnemerObj!=null) {
                                    deleteRecord(deelnemerObj);
                                }
                        }});
                butDelete.setEnabled(false);

                butEmpty = UIHelper.createButton(butDelete = new JButton(), "Leeg/Nieuw", 350, 20, 120, heightField, pRecord);
                butEmpty.addActionListener(
                        new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                emptyAll();
                        }});

                // Switch naar Reservering Panel (CARDLAYOUT)
                butReservering = UIHelper.createButton(butReservering = new JButton(), "Reserveringen", 260, 260, 120, heightField, pRecord);
                butReservering.addActionListener(
                        new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                switchPanel("R");
                        }});
        
        // fill tab pane
        add(pRecord, BorderLayout.CENTER);
        add(pQueryInput, BorderLayout.NORTH);
        addKlantTable();
        emptyAll();
    }
    
    private void fillKlantComboFields() {
        List<Klant> klant = logic.getKlantList();
        Collections.sort(klant);
        cmbKlant_id.setModel(new DefaultComboBoxModel(klant.toArray()));
    }

    private void fillReserveringComboFields() {
        List<Reservering> reservering = logic.getReserveringList();
        cmbReservering_id.setModel(new DefaultComboBoxModel(reservering.toArray()));
    }
    
    
    /**
     * Haal klanten informatie uit database en toon in overzicht JTable (SOUTH)
     * 
     */
    private void addKlantTable() {

        // Gridcontainer
        pDbGrid = new JPanel(new BorderLayout(2, 3));

        // scroll pane eigenschappen
        scrollPaneRes = new JScrollPane(table);
        Dimension d = table.getPreferredSize();
        scrollPaneRes.setPreferredSize(new Dimension(d.width, table.getRowHeight() * numberOfRows));

        // navigatie container
        UIHelper.addNavigation(pNavigation = new JPanel(), table, scrollPaneRes, numberOfRows);

        // kolom eigenschappen - breedte
        Object[] headers = {"Nummer", "Naam", "GebDatum", "Voornaam", "Sex", "Adres", "Postcode", "Woonplaats", "Telefoon", "Email", "Rekening#", "Paspoort#", "Polis#"};
        int[] breedte = {50, 200, 100, 100, 50, 100, 100, 200, 100, 100, 100, 100, 150};

            // tablemodel en eigenschappen instellen, kolombreedte etc
            // tbv renderen celinhoud zijn onderstaande methoden overschreven
            model = new DefaultTableModel(headers, 0) {

                private static final long serialVersionUID = 1L;

                @Override
                public boolean isCellEditable(int row, int column) {
                    return false;
                }

                // rendering van cellen, toont checkbox en juiste datum indien datatype overeenkomstig is
                // null velden veroorzaken fout, standaard maar op String gezet....
                @Override
                public Class getColumnClass(int column) {
                    try {
                        return getValueAt(0, column).getClass();
                    } catch (java.lang.NullPointerException e) {
                        return String.class;
                    }
                }
            };

        table.setModel(model);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        for (int i0 = 0; i0 < breedte.length; i0++) {
            table.getColumnModel().getColumn(i0).setPreferredWidth(breedte[i0]);
        }

        updateKlantTable(true);

        // selecteer klant om hiervan deelnemer te maken, via tabel row door muisklik    
        table.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
               Klant klantRowObj = klantList.get(table.convertRowIndexToModel(table.getSelectedRow()));
               if(klantRowObj!=klantObj && Rules.checkMaxAantalDeelnemers(selectedReservering)) {
                   Utils.errorMessage(pRecord, "Maximum aantal deelnemers", "Maximum aantal deelnemers overschreden");
                   return;
               } else {
                    klantObj=klantRowObj;
                    getRecord(klantObj,null);
               }
            }
        });

        pDbGrid.add(scrollPaneRes, BorderLayout.CENTER);
        pDbGrid.add(pNavigation, BorderLayout.SOUTH);
        add(pDbGrid, BorderLayout.SOUTH);
    }

    /*
     * Vul detailvelden met geselecteerde rowdata
     * @param klant
     * @param deelnemer
     * 
     */
    private void getRecord(Klant klantObj, Deelnemer deelnObj) {
        cmbKlant_id.setSelectedItem(klantObj);
        // is deze klant al deelnemer in deze reservering?
        // dan doorgaan met deze deelnemer!
        if(deelnObj==null) {
            deelnObj=Rules.getDeelnemerFromSelectedKlant(klantObj, selectedReservering);
            deelnemerObj = deelnObj;
        } 
        
        if(deelnObj!=null) {
            txtId.setText("" + deelnObj.getId());
            txtId.setEditable(false);
            cmbKlant_id.setSelectedItem(deelnObj.getKlantId());
            cmbKlant_id.setEnabled(false);
            
            txtBedrag.setText(Utils.getValutaFormatFromNumber(deelnObj.getBedrag()));
            txtBedrag.setEditable(false);
            chkDieet.setSelected(deelnObj.getDieet());
            chkVerlenging.setSelected(deelnObj.getVerlenging());
    
            // verlenging aan/uit afhankelijk reis verlenging mogelijk
            chkVerlenging.setEnabled(deelnObj.getReserveringId().getPlanningId().getReisId().getVerlenging());
        }
    }

    /*
     * update detailvelden in database
     */
    private void updateRecord(Deelnemer deelnObj) {
        deelnObj.setKlantId((Klant) cmbKlant_id.getModel().getSelectedItem());
        deelnObj.setReserveringId((Reservering) cmbReservering_id.getModel().getSelectedItem());
        deelnObj.setBedrag(Utils.getFloatValueOrNull(txtBedrag.getText()));
        deelnObj.setDieet(chkDieet.isSelected());
        deelnObj.setVerlenging(chkVerlenging.isSelected());

        logic.updateDeelnemer(deelnObj);
        logic.berekenReisPrijs(selectedReservering);

        updateReserveringPanel(selectedReservering);
        
        emptyAll();
    }
    
    /*
     * voeg record toe aan database
     */
    private void addRecord() {
        deelnemerObj = new Deelnemer();
        deelnemerObj.setKlantId((Klant) cmbKlant_id.getModel().getSelectedItem());
        deelnemerObj.setReserveringId((Reservering) cmbReservering_id.getModel().getSelectedItem());
        deelnemerObj.setBedrag(Utils.getFloatValueOrNull(txtBedrag.getText()));
        deelnemerObj.setDieet(chkDieet.isSelected());
        deelnemerObj.setVerlenging(chkVerlenging.isSelected());

        logic.addDeelnemer(deelnemerObj);
        // list in memory bijwerken
        selectedReservering.getDeelnemerList().add(deelnemerObj);
        
        logic.berekenReisPrijs(selectedReservering);
        // werk Reserveringscherm bij
        updateReserveringPanel(selectedReservering);

        emptyAll();
    }
    
    /*
     * delete record
     */
    private void deleteRecord(Deelnemer deelnemerObj) {
        logic.deleteDeelnemer(deelnemerObj);
        //updateTable(true);
        emptyAll();

    }
    
    private void searchDeelnemer() {
        String name = txtZoekSleutel.getText();
        //Date startDate = calBeginDatum.getDate();
        //Date endDate = calEindDatum.getDate();

        //deelnemerList = logic.searchDeelnemer(name, startDate, endDate);
        //updateTable(false);
    }
  
    private void emptyAll() {
        txtId.setEditable(false);
        txtId.setText("");
        cmbReservering_id.setEnabled(false);
        cmbKlant_id.setSelectedItem(null);
        txtBedrag.setText("0");
        // wordt automatisch berekend
        txtBedrag.setEditable(false);
        chkDieet.setSelected(false);
        chkVerlenging.setSelected(false);
        
        deelnemerObj=null;
    }

    private void updateKlantTable(Boolean refresh) {
        if (refresh) {
            klantList = logic.getKlantList();
        }
        model.setRowCount(0);
        // data in JTable plaatsen
        for (Klant klant : klantList) {
            Object[] o = {klant.getId(),
                klant.getPersoon().getAchternaam(),
                klant.getPersoon().getGeboortedatum(),
                klant.getPersoon().getVoornaam(),
                klant.getPersoon().getGeslacht(),
                klant.getPersoon().getAdres(),
                klant.getPersoon().getPostcode(),
                klant.getPersoon().getWoonplaats(),
                klant.getPersoon().getTelefoon(),
                klant.getPersoon().getEmail(),
                klant.getPersoon().getRekeningnummer(),
                klant.getPaspoortnummer(),
                klant.getPolisnummer()
            };
            model.addRow(o);
        }
    }

    /**
     * Zoek in Klant
     */
    private void searchKlant() {
        klantList = logic.searchKlant(txtZoekSleutel.getText());
        updateKlantTable(false);
    }
    
    /*
     *  update ReserveringPanel na toevoegen/wijzgen Deelnemer
     *  @param Reservering geselcteerde reservering
     */
    private void updateReserveringPanel(Reservering selectedReservering) {
        reserveringPanel.updateReisPrijs(selectedReservering);
        reserveringPanel.updateTable(true);
        reserveringPanel.updateTableDeelnemer(true, selectedReservering);
        reserveringPanel.getRecord(selectedReservering);
        switchPanel("R");
    }

    /**
    *  SET reference naar geselecteerde Reservering
    *  vul schermitem Reservering
    *  call vanaf ReserveringPanel
    *  
    *  @param resObj 
    */
    public void setSelectedReservering(Reservering resObj) {
        selectedReservering = resObj;
        if(resObj!=null) {
            cmbReservering_id.setSelectedItem(resObj);
            cmbReservering_id.setEnabled(false);
            chkVerlenging.setEnabled(resObj.getPlanningId().getReisId().getVerlenging());
        }
    }

   /**
    *  Pass reference naar geselecteerde Deelnemer
    *  vul schermitem Klant/Deelnemer
    */
    public void setSelectedDeelnemer(Deelnemer deelnObj) {
        selectedDeelnemer = deelnObj;
        deelnemerObj = deelnObj; 
        if(deelnObj!=null) {
            getRecord(null, deelnemerObj);
            cmbKlant_id.setEnabled(false);
        }
    }
    
    /*
     * switch naar panel Reservering
     */
    private void switchPanel(String card) {
        CardLayout c1 = (CardLayout)(cardReservering.getLayout());
        c1.show(cardReservering, card);
    }
    
    
    /**
     * set verwijzing naar bovenliggend ReserveringPanel
     * @param reserveringPanel
     */
    public void setReserveringPanel(ReserveringPanel reserveringPanel) {
        this.reserveringPanel = reserveringPanel;
    }
    
    /**
     * Invoercontrole Deelnemerscherm
     * @return 
     */
    private Boolean isInputOk() {
        
        if(Rules.checkMaximumLeeftijdOverschreden(selectedReservering, klantObj)) {
            Utils.errorMessage(this, "Overschrijding maximum leeftijd", "Deze deelnemer is te oud voor deze reis");
            return false;
        } else {
            return true;
        }
    }
    
}
